#include "slidewidget.h"

SlideWidget::SlideWidget(QWidget *parent) : QWidget(parent)
  ,mousePressed(false)
  ,duration(100)
  ,scale(0.4)
{
    init();
}

/**
 * @brief setWdiget         设置窗口
 * @param pos
 * @param widget
 */
void SlideWidget::setWidget(const SlideWidget::POSITION &pos, QWidget *widget)
{
    if (!widget){
        return;
    }
    widget->setParent(this);
    widget->setGeometry(QRect(0,0,0,1));
    switch (pos){
    case UP:
        upWidget = widget;
        break;
    case DOWN:
        downWidget = widget;
        break;
    case LEFT:
        leftWidget = widget;
        break;
    case RIGHT:
        rightWidget = widget;
        break;
    case CENTRE:
        centreWidget = widget;
        centreWidget->setGeometry(this->rect());
        centreWidget->setVisible(true);
        break;
    default:
        break;
    }
}

/**
 * @brief getWidget     获取窗口
 * @param pos
 * @return
 */
QWidget *SlideWidget::getWidget(const SlideWidget::POSITION &pos)
{
    switch (pos){
    case UP:
        return upWidget;
    case DOWN:
        return downWidget;
    case LEFT:
        return leftWidget;
    case RIGHT:
        return rightWidget;
    case CENTRE:
        return centreWidget;
    default:
        return nullptr;
    }
}

void SlideWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button()==Qt::LeftButton){
        mousePressed = true;
        leftPressPos = event->pos();
    }
    QWidget::mousePressEvent(event);
}

void SlideWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (mousePressed){
        //判断滑动方向
        SlideWidget::ACTION sliderDir = sliderDirection(leftPressPos, event->pos());
        if (sliderDir == SLIDER_INVALID){
            return;
        }
        emit sliderAction(sliderDir);
        switch(sliderDir)
        {
        case  SLIDER_UP:
            //上滑
            sliderUp();
            break;
        case  SLIDER_DOWN:
            //下滑
            sliderDown();
            break;
        case  SLIDER_LEFT:
            //左滑
            sliderLeft();
            break;
        case  SLIDER_RIGHT:
            //右滑
            sliderRight();
            break;
        default:
            break;
        }
    }

    QWidget::mouseMoveEvent(event);
}

void SlideWidget::mouseReleaseEvent(QMouseEvent *event)
{
    mousePressed = false;
    QWidget::mouseReleaseEvent(event);
}

void SlideWidget::leaveEvent(QEvent *event)
{
    mousePressed = false;
    QWidget::leaveEvent(event);
}

void SlideWidget::resizeEvent(QResizeEvent *)
{
    restore();
    if (upWidget){
        upWidget->resize(width(),upWidget->height());
    }
    if (downWidget){
        downWidget->resize(width(),downWidget->height());
    }
    if (leftWidget){
        leftWidget->resize(leftWidget->width(),height());
    }
    if (rightWidget){
        rightWidget->resize(rightWidget->width(), height());
    }
}

QEasingCurve SlideWidget::getEasingCurve() const
{
    return easingCurve;
}

void SlideWidget::setEasingCurve(const QEasingCurve &value)
{
    easingCurve = value;
}

float SlideWidget::getScale() const
{
    return scale;
}

void SlideWidget::setScale(float value)
{
    scale = value;
}

int SlideWidget::getDuration() const
{
    return duration;
}

void SlideWidget::setDuration(int value)
{
    duration = value;
}

void SlideWidget::loop(QPropertyAnimation &animation)
{
    QEventLoop loopEvent;
    connect(&animation,SIGNAL(finished()),&loopEvent,SLOT(quit()));
    animation.start();
    loopEvent.exec();

}

unsigned SlideWidget::getSensitivity() const
{
    return sensitivity;
}

void SlideWidget::setSensitivity(const unsigned &value)
{
    sensitivity = value;
}

/**
 * @brief init          初始化参数
 */
void SlideWidget::init()
{
    currentState = STATE_CENTRE;
    setMouseTracking(true);
    sensitivity=30;
    upWidget=nullptr;downWidget=nullptr;leftWidget=nullptr;rightWidget = nullptr;
    centreWidget = nullptr;
}

/**
 * @brief sliderDirection       获取滑动方向
 * @param startPos
 * @param endPos
 * @return
 */
SlideWidget::ACTION SlideWidget::sliderDirection(const QPoint &startPos,
                                                   const QPoint &endPos)
{
    QPoint point = endPos - startPos;
    if (qMax(abs(point.x()),abs(point.y())) <= (int)sensitivity){
        return SLIDER_INVALID;
    }
    mousePressed = false;
    //横向滑动
    if (abs(point.x())>abs(point.y())){
        return (point.x()>0)?SLIDER_RIGHT:SLIDER_LEFT;
    }else {
        return (point.y()>0)?SLIDER_DOWN:SLIDER_UP;
    }
}

/**
 * @brief restore 还原
 */
void SlideWidget::restore()
{
   if (centreWidget){
       centreWidget->resize(size());
       centreWidget->move(0,0);
       centreWidget->show();
       currentState = STATE_CENTRE;
   }
}

/**
 * @brief sliderUp      向上滑动
 */
void SlideWidget::sliderUp()
{
    if (currentState==STATE_CENTRE && centreWidget && downWidget){
        QPropertyAnimation animationCentre(centreWidget,"geometry");
        animationCentre.setDuration(duration);
        animationCentre.setStartValue(this->rect());
        endRect = QRect(0,0,width(),height()*(1-scale));
        animationCentre.setEndValue(endRect);
        animationCentre.setEasingCurve(easingCurve);

        QPropertyAnimation animationDown(downWidget,"geometry");
        animationDown.setDuration(duration);
        animationDown.setStartValue(QRect(0,height(),width(),0));
        endRect1 = QRect(0,height()*(1-scale),width(),height()*scale);
        animationDown.setEndValue(endRect1);
        animationDown.setEasingCurve(easingCurve);
        animationCentre.start();
        currentState = STATE_DOWN;
        loop(animationDown);
        centreWidget->setGeometry(endRect);
        downWidget->setGeometry(endRect1);
    }else if (currentState==STATE_UP && centreWidget && upWidget){
        QPropertyAnimation animationCentre(upWidget,"geometry");
        animationCentre.setDuration(duration);
        animationCentre.setStartValue(QRect(0,0,width(),height()*scale));
        endRect=QRect(0,0,width(),0);
        animationCentre.setEndValue(endRect);
        animationCentre.setEasingCurve(easingCurve);

        QPropertyAnimation animationDown(centreWidget,"geometry");
        animationDown.setDuration(duration);
        animationDown.setStartValue(QRect(0,height()*scale,width(),height()*(1-scale)));
        endRect1 = this->rect();
        animationDown.setEndValue(endRect1);
        animationDown.setEasingCurve(easingCurve);
        animationCentre.start();
        currentState = STATE_CENTRE;
        loop(animationDown);
        upWidget->setGeometry(endRect);
        centreWidget->setGeometry(endRect1);
    }
}

/**
 * @brief sliderDown    向下滑动
 */
void SlideWidget::sliderDown()
{
    if (currentState==STATE_CENTRE && centreWidget && upWidget){
        QPropertyAnimation animationCentre(centreWidget,"geometry");
        animationCentre.setDuration(duration);
        animationCentre.setStartValue(this->rect());
        endRect = QRect(0,height()*scale,width(),height()*(1-scale));
        animationCentre.setEndValue(endRect);
        animationCentre.setEasingCurve(easingCurve);

        QPropertyAnimation animationDown(upWidget,"geometry");
        animationDown.setDuration(duration);
        animationDown.setStartValue(QRect(0,0,width(),0));
        endRect1 = QRect(0,0,width(),height()*scale);
        animationDown.setEndValue(endRect1);
        animationDown.setEasingCurve(easingCurve);
        animationCentre.start();
        currentState = STATE_UP;
        loop(animationDown);
        centreWidget->setGeometry(endRect);
        upWidget->setGeometry(endRect1);
    }else if (currentState==STATE_DOWN && centreWidget && downWidget){
        QPropertyAnimation animationCentre(downWidget,"geometry");
        animationCentre.setDuration(duration);
        animationCentre.setStartValue(downWidget->geometry());
        endRect = QRect(0,height(),width(),0);
        animationCentre.setEndValue(endRect);
        animationCentre.setEasingCurve(easingCurve);

        QPropertyAnimation animationDown(centreWidget,"geometry");
        animationDown.setDuration(duration);
        animationDown.setStartValue(QRect(0,0,width(),height()*(1-scale)));
        endRect1 = this->rect();
        animationDown.setEndValue(endRect1);
        animationDown.setEasingCurve(easingCurve);
        animationCentre.start();
        currentState = STATE_CENTRE;
        loop(animationDown);
        downWidget->setGeometry(endRect);
        centreWidget->setGeometry(endRect1);
    }
}

/**
 * @brief sliderLeft    向左滑动
 */
void SlideWidget::sliderLeft()
{
    if (currentState==STATE_CENTRE && centreWidget && rightWidget){
        QPropertyAnimation animationCentre(centreWidget,"geometry");
        animationCentre.setDuration(duration);
        QRect rect = this->rect();
        animationCentre.setStartValue(rect);
        rect.setWidth(width()*(1-scale));
        endRect = rect;
        animationCentre.setEndValue(rect);
        animationCentre.setEasingCurve(easingCurve);

        QPropertyAnimation animationDown(rightWidget,"geometry");
        animationDown.setDuration(duration);
        animationDown.setStartValue(rightWidget->geometry());
        endRect1 = QRect(rect.width(),0,width()*scale,rect.height());
        animationDown.setEndValue(endRect1);
        animationDown.setEasingCurve(easingCurve);
        animationCentre.start();
        currentState = STATE_RIGHT;
        loop(animationDown);
        centreWidget->setGeometry(endRect);
        rightWidget->setGeometry(endRect1);
    }else if (currentState==STATE_LEFT && centreWidget && leftWidget){
        QPropertyAnimation animationCentre(leftWidget,"geometry");
        animationCentre.setDuration(duration);
        animationCentre.setStartValue(leftWidget->geometry());
        endRect = QRect(0,0,0,height());
        animationCentre.setEndValue(endRect);
        animationCentre.setEasingCurve(easingCurve);

        QPropertyAnimation animationDown(centreWidget,"geometry");
        animationDown.setDuration(duration);
        animationDown.setStartValue(centreWidget->geometry());
        endRect1 = rect();
        animationDown.setEndValue(endRect1);
        animationDown.setEasingCurve(easingCurve);
        animationCentre.start();
        currentState = STATE_CENTRE;
        loop(animationDown);
        leftWidget->setGeometry(endRect);
        centreWidget->setGeometry(endRect1);
    }
}

/**
 * @brief sliderRight   向右滑动
 */
void SlideWidget::sliderRight()
{
    if (currentState==STATE_CENTRE && centreWidget && leftWidget){
        QPropertyAnimation animationCentre(centreWidget,"geometry");
        animationCentre.setDuration(duration);
        animationCentre.setStartValue(rect());
        endRect1 = QRect(width()*scale,0,width()*(1-scale),height());
        animationCentre.setEndValue(endRect1);
        animationCentre.setEasingCurve(easingCurve);

        QPropertyAnimation animationDown(leftWidget,"geometry");
        animationDown.setDuration(duration);
        animationDown.setStartValue(leftWidget->geometry());
        endRect = QRect(0,0,width()*scale,height());
        animationDown.setEndValue(endRect);
        animationDown.setEasingCurve(easingCurve);
        animationCentre.start();
        currentState = STATE_LEFT;
        loop(animationDown);
        leftWidget->setGeometry(endRect);
        centreWidget->setGeometry(endRect1);
    }else if (currentState==STATE_RIGHT && centreWidget && rightWidget){
        QPropertyAnimation animationCentre(rightWidget,"geometry");
        animationCentre.setDuration(duration);
        animationCentre.setStartValue(rightWidget->geometry());
        endRect = QRect(width(),0,0,height());
        animationCentre.setEndValue(endRect);
        animationCentre.setEasingCurve(easingCurve);

        QPropertyAnimation animationDown(centreWidget,"geometry");
        animationDown.setDuration(duration);
        animationDown.setStartValue(centreWidget->rect());
        endRect1 = this->rect();
        animationDown.setEndValue(endRect1);
        animationDown.setEasingCurve(easingCurve);
        animationCentre.start();
        currentState = STATE_CENTRE;
        loop(animationDown);
        rightWidget->setGeometry(endRect);
        centreWidget->setGeometry(endRect1);
    }
}

SlideWidget::CURRENTWIDGET SlideWidget::getCurrentPos() const
{
    return currentState;
}

void SlideWidget::setCurrentPos(const SlideWidget::CURRENTWIDGET &value)
{
    currentState = value;
}


